#include "line_sfx.h"
#include "ui/ui_widget.h"
#include "font/font.h"
#include "num/rand.h"
#include "graphics/graphics_util.h"

#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

using namespace vfx;



LineSFX::LineSFX(EffectMan*	pParent, const std::string& PartSys, float GenRate) :
	SFXSet(pParent),
	m_pCurrent(NULL),
	m_pSys(NULL),
	m_GenRate(GenRate)
{
	m_pSys = new part2d::Part2D();
	m_pSys->Load(PartSys);
}
LineSFX::~LineSFX()
{
	UTIL_SAFE_DELETE(m_pSys);
	UTIL_SAFE_DELETE(m_pCurrent);
}
void	LineSFX::Render(const math::Vec2& Offset,float Scale)
{
	if (m_pSys)
		m_pSys->Render(Offset, 1);
}


void	LineSFX::Tick(float dt)
{
	for (int i=(int)(m_Lines.size())-1; i>=0; i--)
	{
		LineSet*	pSet = m_Lines[i];
		pSet->Progress.Tick(dt);
		if (pSet->Progress.IsReady())
		{
			pSet->Progress.Reset();
			pSet->LineIndex++;
			if (pSet->LineIndex >= (int)pSet->Lines.size())
			{
				delete pSet;
				m_Lines.erase(m_Lines.begin()+i);
				continue;
			}
		}
		pSet->GenRate.Tick(dt);
		if (pSet->GenRate.IsReady())
		{
			pSet->GenRate.Reset();
			// add a new particle
			if (m_pSys && pSet->LineIndex < pSet->Lines.size())
			{
				// work out which line
				math::Vec2		Pos = pSet->Lines[pSet->LineIndex].From + 
									  (pSet->Lines[pSet->LineIndex].Delta*pSet->Progress.GetProgress());

				m_pSys->TriggerParticle(Pos);
			}
		}
	}
	if (m_pSys)
		m_pSys->Tick(dt);
}


void	LineSFX::BeginSet(float	Time)
{
	UTIL_SAFE_DELETE(m_pCurrent);
	m_pCurrent = new	LineSet;
	m_pCurrent->LineIndex = 0;
	m_pCurrent->Progress.SetLimit(Time);
	m_pCurrent->GenRate.SetLimit(m_GenRate);
}


void	LineSFX::CloseSet()
{
	if (m_pCurrent)
	{
		m_Lines.push_back(m_pCurrent);
		m_pCurrent = NULL;
	}
}


void	LineSFX::AddLine(const math::Vec2& From, const math::Vec2& To)
{
	if (m_pCurrent)
	{
		LineInst	NewLine;
		NewLine.From = From;
		NewLine.Delta = To-From;
		m_pCurrent->Lines.push_back(NewLine);
	}
}

void	LineSFX::MakeBox(const math::Vec2& TL, const math::Vec2& BR, float Time)
{
	// clockwise
	math::Vec2	TR(BR.x, TL.y);
	math::Vec2	BL(TL.x, BR.y);
	BeginSet(Time);
		AddLine(TR, BR);
		AddLine(BR, BL);
		AddLine(BL, TL);
		AddLine(TL, TR);
	CloseSet();
}


